package org.lex.dbq.view.template;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.lex.dbq.model.bo.JdbcUrl;
import org.lex.dbq.model.bo.JdbcUrlTemplate;
import org.lex.dbq.model.bo.Session;
import org.lex.dbq.model.service.ServiceFactory;
import org.lex.dbq.model.service.SessionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConnectTemplateDialog extends Dialog {
	public static void main(String[] args) {
		new ConnectTemplateDialog(null).open();
		Display.getCurrent().dispose();
	}

	public static JdbcUrl showConnect(Shell parent, String templateName) {
		ConnectTemplateDialog dia = new ConnectTemplateDialog(parent);
		dia.initTemplateName = templateName;
		dia.open();
		return dia.getJdbcUrl();
	}

	private String initTemplateName = null;

	private JdbcUrl finalUrl = null;

	private Button saveSession = null;
	private Button saveUserAndPassword = null;
	private Text sessionName = null;
	private Label sessionNameLabel = null;

	private Combo templateCombo = null;
	private Group stackGroup = null;
	private StackLayout stackLayout = null;
	private Map<String, JdbcUrlTemplatePane> paneMap = new HashMap<String, JdbcUrlTemplatePane>();

	private Logger log = LoggerFactory.getLogger(ConnectTemplateDialog.class);

	public ConnectTemplateDialog(Shell parentShell) {
		super(parentShell);
		this.setBlockOnOpen(true);
		this.setShellStyle(SWT.MAX | SWT.RESIZE);
	}

	public JdbcUrl getJdbcUrl() {
		return finalUrl;
	}

	@Override
	protected void cancelPressed() {
		finalUrl = null;
		super.cancelPressed();
	}

	@Override
	protected void okPressed() {
		JdbcUrlTemplatePane pane = null;
		// build url
		if (stackLayout.topControl instanceof JdbcUrlTemplatePane) {
			pane = (JdbcUrlTemplatePane) stackLayout.topControl;
			finalUrl = pane.getJdbcUrl();
		} else {
			log.info("No template selected");
			finalUrl = null;
		}
		// save session
		if (true == saveSession.getSelection() && null != finalUrl) {
			String name = sessionName.getText();
			log.info("save session name=" + name);
			JdbcUrlTemplate url = this.getSelectedTemplate();
			if (null != url) {
				Session s = new Session();
				s.setUrl(finalUrl.getUrl());
				s.setName(sessionName.getText());
				s.setDriver(finalUrl.getDriver());

				if (true == saveUserAndPassword.getSelection()) {
					log.warn("save user and password");
					s.setUser(finalUrl.getUser());
					s.setPassword(finalUrl.getPassword());
				}

				SessionService service = ServiceFactory.getSessionService();
				service.add(s);
				try {
					service.store();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		super.okPressed();
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText("Connect");
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		// pane = new JdbcUrlTemplatePane(parent, template);
		GridLayout layout = new GridLayout();
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = 1;

		Composite pane = new Composite(parent, SWT.NONE);
		pane.setLayoutData(new GridData(GridData.FILL_BOTH));
		pane.setLayout(layout);
		this.createTemplatePane(pane);
		this.createStackPane(pane);
		this.createSessionGroup(pane);

		if (null != initTemplateName) {
			templateCombo.select(templateCombo.indexOf(initTemplateName));
			this.selectedTemplateChanged(initTemplateName);
			this.getShell().pack(true);
		}

		setSaveSession(saveSession.getSelection());

		return parent;
	}

	private void setSaveSession(boolean b) {
		sessionName.setEnabled(b);
		sessionNameLabel.setEnabled(b);
		saveUserAndPassword.setEnabled(b);
	}

	private JdbcUrlTemplate getSelectedTemplate() {
		JdbcUrlTemplate url = null;
		String name = this.getSelectedTemplateName();
		if (null != name) {
			url = ServiceFactory.getTemplateService().getByName(name);
		}
		log.info("select template=" + url);
		return url;
	}

	private String getSelectedTemplateName() {
		int index = templateCombo.getSelectionIndex();
		log.debug("select template index=" + index);
		if (index >= 0) {
			String name = templateCombo.getItem(index);
			log.debug("select template name=" + name);
			return name;
		} else {
			return null;
		}
	}

	private void selectedTemplateChanged(String name) {
		if (null == name) {
			return;
		}
		JdbcUrlTemplate url = this.getSelectedTemplate();
		JdbcUrlTemplatePane pane = paneMap.get(name);
		if (null == pane) {
			pane = new JdbcUrlTemplatePane(stackGroup, url);
			paneMap.put(name, pane);
			log.info("add pane by url=" + url);
		}
		stackLayout.topControl = pane;
		stackGroup.setText(name);
		stackGroup.layout();

		sessionName.setText(name);

		getShell().pack();
	}

	private Composite createTemplatePane(Composite parent) {
		GridLayout layout = new GridLayout();
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = 2;

		GridData d = new GridData(GridData.FILL_HORIZONTAL);
		d.verticalSpan = 1;
		d.horizontalSpan = 1;

		Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
		group.setText("Template");
		group.setLayoutData(d);
		group.setLayout(layout);

		{
			d = new GridData();
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			Label label = new Label(group, SWT.NONE);
			label.setText("Template");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			templateCombo = new Combo(group, SWT.READ_ONLY);
			templateCombo.setLayoutData(d);
			String[] names = ServiceFactory.getTemplateService().getAllNames().toArray(new String[0]);
			Arrays.sort(names);
			for (String name : names) {
				templateCombo.add(name);
			}
			templateCombo.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					selectedTemplateChanged(getSelectedTemplateName());
				}
			});
		}
		return group;
	}

	private Composite createStackPane(Composite parent) {
		GridData d = new GridData(GridData.FILL_BOTH);
		d.verticalSpan = 1;
		d.horizontalSpan = 1;

		stackLayout = new StackLayout();

		stackGroup = new Group(parent, SWT.SHADOW_ETCHED_IN);
		stackGroup.setLayoutData(d);
		stackGroup.setText("Parameter");
		stackGroup.setLayout(stackLayout);
		return stackGroup;
	}

	private Group createSessionGroup(Composite parent) {
		GridLayout layout = new GridLayout();
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = 2;

		GridData d = new GridData(GridData.FILL_HORIZONTAL);
		d.verticalSpan = 1;
		d.horizontalSpan = 1;

		Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
		group.setLayout(layout);
		group.setLayoutData(d);
		group.setText("Session");

		{
			d = new GridData();
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			saveSession = new Button(group, SWT.CHECK);
			saveSession.setLayoutData(d);
			saveSession.setText("Save session");
			saveSession.setSelection(false);
			saveSession.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					boolean enabled = saveSession.getSelection();
					setSaveSession(enabled);
				}
			});

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			saveUserAndPassword = new Button(group, SWT.CHECK);
			saveUserAndPassword.setLayoutData(d);
			saveUserAndPassword.setText("Save User and Password");
			saveUserAndPassword.setSelection(true);
		}
		{
			d = new GridData();
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			sessionNameLabel = new Label(group, SWT.NONE);
			sessionNameLabel.setLayoutData(d);
			sessionNameLabel.setText("Session Name");

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			sessionName = new Text(group, SWT.BORDER);
			sessionName.setLayoutData(d);
		}
		return group;
	}
}
